﻿using System.Diagnostics;
using System.Runtime.InteropServices;
using RDF;

using stepengine = RDF.ifcengine;

#if _WIN64
using int_t = System.Int64;
#else
using int_t = System.Int32;
#endif

namespace DZJIFC.Model
{
    public class AP242Product : Geometry
    {
        #region Methods

        public AP242Product(int_t iInstance)
            : base(GeometryType.AP242)
        {
            // Geometry
            Instance = iInstance;

            // Attributes
            stepengine.sdaiGetAttrBN(iInstance, "id", stepengine.sdaiUNICODE, out IntPtr pAttribute);
            Id = Marshal.PtrToStringUni(pAttribute);

            stepengine.sdaiGetAttrBN(iInstance, "name", stepengine.sdaiUNICODE, out pAttribute);
            Name = UniqueName = Marshal.PtrToStringUni(pAttribute);

            stepengine.sdaiGetAttrBN(iInstance, "description", stepengine.sdaiUNICODE, out pAttribute);
            Description = Marshal.PtrToStringUni(pAttribute);

            int_t iFormationInstance = 0;
            stepengine.sdaiGetAttrBN(iInstance, "formation", stepengine.sdaiINSTANCE, out iFormationInstance);
            Debug.Assert(iFormationInstance != 0);

            int_t iProductInstance = 0;
            stepengine.sdaiGetAttrBN(iFormationInstance, "of_product", stepengine.sdaiINSTANCE, out iProductInstance);
            Debug.Assert(iProductInstance != 0);

            stepengine.sdaiGetAttrBN(iProductInstance, "id", stepengine.sdaiUNICODE, out pAttribute);
            FormationId = Marshal.PtrToStringUni(pAttribute);

            stepengine.sdaiGetAttrBN(iProductInstance, "name", stepengine.sdaiUNICODE, out pAttribute);
            FormationName = Marshal.PtrToStringUni(pAttribute);

            UniqueName = string.Format("#{0} {1} {2}", ExpressID, FormationName, IModelStructureView.ITEM_PRODUCT);

            Calculate();
        }

        public override void Scale(float fScaleFactor)
        {
            base.Scale(fScaleFactor);

            foreach (var instance in Instances)
            {
                if (instance.Transformation != null)
                {
                    instance.Transformation._41 /= fScaleFactor;
                    instance.Transformation._42 /= fScaleFactor;
                    instance.Transformation._43 /= fScaleFactor;
                }
            }
        }

        #endregion // Methods

        #region Properties

        public string Id { get; private set; }
        public string Description { get; private set; }
        public string FormationId { get; private set; }
        public string FormationName { get; private set; }
        public long ExpressID => stepengine.internalGetP21Line(Instance);
        public int_t RelatingProductsCount { get; set; } // if == 0 then it has geometry, otherwise it is a placeholder
        public int_t RelatedProductsCount { get; set; } // if == 0 then it is a root element

        #endregion // Properties
    }

    public class AP242InstancesIterator
    {
        #region Methods

        public AP242InstancesIterator(AP242Product product)
        {
            if (product == null)
            {
                throw new ArgumentNullException();
            }

            Product = product;
        }
        public AP242Instance? GetNextInstance()
        {
            if (++Index >= Product.Instances.Count)
            {
                Index = -1;

                return null;
            }

            return Product.Instances[Index] as AP242Instance;
        }

        #endregion // Methods

        #region Properties

        private AP242Product Product { get; set; }

        private int Index { get; set; } = -1;

        #endregion // Properties
    }
}
